package cn.xiaohaoo.medicine.util.mongo;

import com.mongodb.MongoClient;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.result.DeleteResult;
import org.bson.Document;

import java.io.IOException;
import java.util.*;
import java.util.function.Consumer;

/**
 * 操作mongo的工具类
 *
 * @author 小浩
 */
public class MongoDatabaseUtils {

    public static final String MEDICINE_DETAIL_DATABASE = "medicine_detail";

    public static final String COLLECTION_MEDICINE_OUTLINE = "medicine_outline";
    public static final String COLLECTION_MEDICINE_TYPE = "medicine_type";

    public static final String MEDICINE_DETAIL_COLLECTION = "medicine_detail";
    public static final String COLLECTION_IMGS = "imgs";
    public static final String COLLECTION_IMGS2 = "imgs2";

    private static String HOST;
    private static Integer PORT;

    static {
        Properties properties = new Properties();
        try {
            properties.load(ClassLoader.getSystemResourceAsStream("mongodb.properties"));
            HOST = properties.getProperty("host");
            PORT = Integer.valueOf(properties.getProperty("port"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static final ThreadLocal<MongoClient> MONGO_CLIENT =
        ThreadLocal.withInitial(() -> new MongoClient(new ServerAddress(HOST, PORT)));

    /**
     * 形参格式：
     * 1. 待插入的数据
     */
    public static void insertDocument(String collectionName, Document document) {
        MongoCollection<Document> collection =
            MONGO_CLIENT.get().getDatabase(MEDICINE_DETAIL_DATABASE).getCollection(collectionName);
        collection.insertOne(document);
    }


    public static void updateDocument(String collectionName, Document source, Document dest) {
        MongoCollection<Document> collection =
            MONGO_CLIENT.get().getDatabase(MEDICINE_DETAIL_DATABASE).getCollection(collectionName);
        collection.updateOne(source, dest);
    }

    /**
     * 形参格式：参考insertDocument方法
     */
    public static void insertDocuments(String collectionName, List<Document> documents) {
        MongoCollection<Document> collection =
            MONGO_CLIENT.get().getDatabase(MEDICINE_DETAIL_DATABASE).getCollection(collectionName);
        collection.insertMany(documents);
    }

    /**
     * 查询数据库下所有的集合
     *
     * @param databaseName
     * @return
     */
    public static List<String> queryAllCollections(String databaseName) {
        List<String> list = new ArrayList<>();
        MONGO_CLIENT.get().getDatabase(databaseName).listCollectionNames().forEach((Consumer<? super String>) list::add);
        return list;
    }


    /**
     * 查询一个集合下所有的文档
     *
     * @return
     */
    public static List<Map<String, Object>> queryAllDocuments(String collectionName) {
        MongoCollection<Document> collection =
            MONGO_CLIENT.get().getDatabase(MEDICINE_DETAIL_DATABASE).getCollection(collectionName);
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        collection.find().forEach((Consumer<? super Document>) v -> {
            list.add(new HashMap<>(v));
        });
        return list;
    }


    /**
     * 根据集合名字查询文档
     *
     * @param findDocument
     * @return
     */
    public static Document queryDocumentByName(String collectionName, Document findDocument) {
        return MONGO_CLIENT.get().getDatabase(MEDICINE_DETAIL_DATABASE).getCollection(collectionName).find(findDocument).first();
    }


    /**
     * 根据findDocument删除文档
     *
     * @param findDocument
     * @return
     */
    public static boolean deleteDocument(String collectionName, Document findDocument) {
        DeleteResult deleteResult =
            MONGO_CLIENT.get().getDatabase(MEDICINE_DETAIL_DATABASE).getCollection(collectionName).deleteOne(findDocument);
        return deleteResult.getDeletedCount() == 1;
    }
}
